<template>
  <div class="molecule-viewer">
    <div ref="container" class="viewer-container"></div>
    <div v-if="loading" class="loading-overlay">
      <div class="loading-spinner"></div>
      <p>Loading molecule...</p>
    </div>
    <div v-if="error" class="error-overlay">
      <p>{{ error }}</p>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch, markRaw } from 'vue';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

const props = defineProps({
  structureData: {
    type: Object,
    default: null
  },
  materialId: {
    type: String,
    default: ''
  },
  materialData: {
    type: Object,
    default: null
  },
  displayMode: {
    type: String,
    default: 'ball' // 'ball' 或 'stick'
  },
  crystalMode: {
    type: Boolean,
    default: false // 是否显示晶体结构
  },
  unitCells: {
    type: Number,
    default: 1 // 显示的晶胞数量（1x1x1, 2x2x2, 3x3x3等）
  }
});

// Debug props on component creation
console.log('MoleculeViewer created with props:', {
  structureData: props.structureData,
  materialId: props.materialId,
  materialData: props.materialData
});

const container = ref(null);
const scene = ref(null);
const camera = ref(null);
const renderer = ref(null);
const controls = ref(null);
const loading = ref(false);
const error = ref('');
const hiddenElements = ref(new Set()); // 存储被隐藏的元素类型

let animationId = null;

// 原子颜色映射
const atomColors = {
  'H': 0xFFFFFF,  // 白色
  'C': 0x909090,  // 灰色
  'N': 0x3050F8,  // 蓝色
  'O': 0xFF0D0D,  // 红色
  'F': 0x90E050,  // 绿色
  'Cl': 0x1FF01F, // 绿色
  'Br': 0xA62929, // 深红色
  'I': 0x940094,  // 紫色
  'He': 0xD9FFFF, // 青色
  'Ne': 0xB3E3F5, // 浅蓝色
  'Ar': 0x80D1E3, // 蓝绿色
  'Xe': 0x429EB0, // 深蓝绿色
  'Kr': 0x5CB8D1, // 中蓝绿色
  'P': 0xFF8000,  // 橙色
  'S': 0xFFFF30,  // 黄色
  'B': 0xFFB5B5,  // 粉红色
  'Li': 0xCC80FF, // 紫色
  'Na': 0xAB5CF2, // 紫色
  'K': 0x8F40D4,  // 紫色
  'Rb': 0x702EB0, // 紫色
  'Cs': 0x57178F, // 紫色
  'Be': 0xC2FF00, // 黄绿色
  'Mg': 0x8AFF00, // 黄绿色
  'Ca': 0x3DFF00, // 绿色
  'Sr': 0x00FF00, // 绿色
  'Ba': 0x00C700, // 深绿色
  'Ra': 0x00A500, // 深绿色
  'Ti': 0xBFC2C7, // 银灰色
  'Fe': 0xE06633, // 橙色
  'default': 0xFF69B4 // 粉色（默认）
};

// 原子半径（范德华半径，单位：Å）
const atomRadii = {
  'H': 1.20,
  'C': 1.70,
  'N': 1.55,
  'O': 1.52,
  'F': 1.47,
  'Cl': 1.75,
  'Br': 1.85,
  'I': 1.98,
  'He': 1.40,
  'Ne': 1.54,
  'Ar': 1.88,
  'Xe': 2.16,
  'Kr': 2.02,
  'P': 1.80,
  'S': 1.80,
  'B': 1.92,
  'Li': 1.82,
  'Na': 2.27,
  'K': 2.75,
  'Rb': 3.03,
  'Cs': 3.43,
  'Be': 1.53,
  'Mg': 1.73,
  'Ca': 2.31,
  'Sr': 2.49,
  'Ba': 2.68,
  'Ra': 2.83,
  'Ti': 2.00,
  'Fe': 2.00,
  'default': 1.80
};

const initThreeJS = () => {
  console.log('initThreeJS called, container:', container.value);
  if (!container.value) {
    console.error('Container is null in initThreeJS');
    return;
  }

  // 创建场景 - 使用 markRaw 防止 Vue 代理
  scene.value = markRaw(new THREE.Scene());
  scene.value.background = new THREE.Color(0x0a0a0a);

  // 创建相机 - 使用 markRaw
  camera.value = markRaw(new THREE.PerspectiveCamera(
    75,
    container.value.clientWidth / container.value.clientHeight,
    0.1,
    1000
  ));
  camera.value.position.z = 15;

  // 创建渲染器 - 使用 markRaw
  try {
    renderer.value = markRaw(new THREE.WebGLRenderer({
      antialias: true,
      alpha: true,
      powerPreference: 'high-performance'
    }));
    
    renderer.value.setSize(container.value.clientWidth, container.value.clientHeight);
    renderer.value.setPixelRatio(window.devicePixelRatio);
    
    // 确保canvas有明确的样式
    const canvas = renderer.value.domElement;
    canvas.style.display = 'block';
    canvas.style.width = '100%';
    canvas.style.height = '100%';
    
    container.value.appendChild(canvas);
    
  } catch (error) {
    console.error("Failed to create WebGL renderer:", error);
    error.value = "WebGL renderer creation failed: " + error.message;
    return;
  }

  // 添加轨道控制 - 使用 markRaw
  controls.value = markRaw(new OrbitControls(camera.value, renderer.value.domElement));
  controls.value.enableDamping = true;
  controls.value.dampingFactor = 0.05;

  // 添加环境光 - 使用 markRaw
  const ambientLight = markRaw(new THREE.AmbientLight(0x404040, 0.6));
  scene.value.add(ambientLight);

  // 添加定向光 - 使用 markRaw
  const directionalLight = markRaw(new THREE.DirectionalLight(0xffffff, 0.8));
  directionalLight.position.set(1, 1, 1);
  scene.value.add(directionalLight);

  // 添加点光源 - 使用 markRaw
  const pointLight = markRaw(new THREE.PointLight(0xffffff, 0.5));
  pointLight.position.set(5, 5, 5);
  scene.value.add(pointLight);

  animate();
  console.log('Three.js initialization completed successfully');
  console.log('Scene created:', !!scene.value);
  console.log('Camera created:', !!camera.value);
  console.log('Renderer created:', !!renderer.value);
};

const animate = () => {
  animationId = requestAnimationFrame(animate);
  
  if (controls.value && typeof controls.value.update === 'function') {
    try {
      controls.value.update();
    } catch (e) {
      console.error('Error in controls update:', e);
    }
  }
  
  if (renderer.value && scene.value && camera.value) {
    try {
      renderer.value.render(scene.value, camera.value);
    } catch (e) {
      console.error('Error in render:', e);
    }
  }
};

const renderMolecule = (structureData) => {
  console.log('renderMolecule called with structure data:', !!structureData);
  console.log('Display mode:', props.displayMode);
  
  if (!scene.value || !structureData) {
    console.log('Cannot render: scene or structure data missing');
    console.log('Scene available:', !!scene.value);
    console.log('Structure data available:', !!structureData);
    return;
  }
  
  // Check if this is the same data we already rendered
  const currentMaterialId = structureData.material_id || props.materialId;
  const currentDisplayMode = props.displayMode;
  const currentCrystalMode = props.crystalMode;
  const currentUnitCells = props.unitCells;
  
  // 在晶体模式下切换元素可见性时，即使设置相同也需要重新渲染
  const isCrystalToggle = props.crystalMode &&
                         scene.value.userData &&
                         scene.value.userData.lastRenderedMaterialId === currentMaterialId &&
                         scene.value.userData.lastDisplayMode === currentDisplayMode &&
                         scene.value.userData.lastCrystalMode === currentCrystalMode &&
                         scene.value.userData.lastUnitCells === currentUnitCells;
  
  if (isCrystalToggle) {
    console.log('Same material and display settings, but re-rendering for crystal toggle');
  } else if (scene.value.userData &&
      scene.value.userData.lastRenderedMaterialId === currentMaterialId &&
      scene.value.userData.lastDisplayMode === currentDisplayMode &&
      scene.value.userData.lastCrystalMode === currentCrystalMode &&
      scene.value.userData.lastUnitCells === currentUnitCells) {
    console.log('Same material and display settings already rendered, skipping');
    console.log('Preserving hidden elements:', Array.from(hiddenElements.value));
    return;
  }

  // 清除现有场景内容
  while(scene.value.children.length > 0) {
    scene.value.remove(scene.value.children[0]);
  }

  // 重新添加灯光 - 使用 markRaw
  const ambientLight = markRaw(new THREE.AmbientLight(0x404040, 0.6));
  scene.value.add(ambientLight);

  const directionalLight = markRaw(new THREE.DirectionalLight(0xffffff, 0.8));
  directionalLight.position.set(1, 1, 1);
  scene.value.add(directionalLight);

  const pointLight = markRaw(new THREE.PointLight(0xffffff, 0.5));
  pointLight.position.set(5, 5, 5);
  scene.value.add(pointLight);

  try {
    if (structureData.sites && structureData.lattice) {
      const atoms = structureData.sites;
      const lattice = structureData.lattice;
      
      console.log('Rendering molecule with:', atoms.length, 'atoms');
      console.log('Lattice parameters:', lattice);
      console.log('Display mode:', props.displayMode);
      console.log('Crystal mode:', props.crystalMode);
      console.log('Unit cells:', props.unitCells);

      // 根据显示模式选择渲染方法
      if (props.crystalMode) {
        // 晶体模式：显示多个晶胞和晶胞边界
        renderCrystalStructure(atoms, lattice);
      } else if (props.displayMode === 'stick') {
        renderStickMode(atoms, lattice);
      } else {
        renderBallMode(atoms, lattice);
      }

      // 自动调整相机位置 - 基于原子分布
      let minX = Infinity, maxX = -Infinity;
      let minY = Infinity, maxY = -Infinity;
      let minZ = Infinity, maxZ = -Infinity;
      
      scene.value.children.forEach(child => {
        if (child.isMesh) {
          minX = Math.min(minX, child.position.x);
          maxX = Math.max(maxX, child.position.x);
          minY = Math.min(minY, child.position.y);
          maxY = Math.max(maxY, child.position.y);
          minZ = Math.min(minZ, child.position.z);
          maxZ = Math.max(maxZ, child.position.z);
        }
      });
      
      // 确保我们有有效的范围
      if (minX === Infinity) {
        minX = -5; maxX = 5;
        minY = -5; maxY = 5;
        minZ = -5; maxZ = 5;
      }
      
      const centerX = (minX + maxX) / 2;
      const centerY = (minY + maxY) / 2;
      const centerZ = (minZ + maxZ) / 2;
      
      const sizeX = Math.max(maxX - minX, 1);
      const sizeY = Math.max(maxY - minY, 1);
      const sizeZ = Math.max(maxZ - minZ, 1);
      const maxSize = Math.max(sizeX, sizeY, sizeZ, 5);
      
      // 根据结构大小调整相机距离
      const cameraDistance = maxSize * 2.5;
      
      // 将相机定位在结构上方和侧方
      camera.value.position.set(
        centerX + cameraDistance,
        centerY + cameraDistance * 0.7,
        centerZ + cameraDistance
      );
      camera.value.lookAt(centerX, centerY, centerZ);
      controls.value.target.set(centerX, centerY, centerZ);
      controls.value.update();

      // 添加图例
      createAtomLegend();
      
      // 添加分子标题
      createMoleculeTitle();
      
      // 添加额外的灯光以提高场景亮度
      addAdditionalLighting();
      
      // Store the last rendered material ID and display mode to prevent re-rendering the same material
      scene.value.userData = scene.value.userData || {};
      scene.value.userData.lastRenderedMaterialId = structureData.material_id || props.materialId;
      scene.value.userData.lastDisplayMode = props.displayMode;
      scene.value.userData.lastCrystalMode = props.crystalMode;
      scene.value.userData.lastUnitCells = props.unitCells;
      console.log('Molecule rendered successfully for material:', structureData.material_id || props.materialId,
                  'with mode:', props.displayMode,
                  'crystal mode:', props.crystalMode,
                  'unit cells:', props.unitCells);
    }
  } catch (err) {
    console.error('Error rendering molecule:', err);
    error.value = 'Failed to render molecule structure: ' + err.message;
  }
};

// 创建原子标签（可选功能）
const createAtomLabel = (element, x, y, z) => {
  const canvas = document.createElement('canvas');
  const context = canvas.getContext('2d');
  canvas.width = 64;
  canvas.height = 64;

  context.fillStyle = 'white';
  context.font = '24px Arial';
  context.textAlign = 'center';
  context.textBaseline = 'middle';
  context.fillText(element, 32, 32);

  const texture = new THREE.CanvasTexture(canvas);
  const material = new THREE.SpriteMaterial({ map: texture });
  const sprite = new THREE.Sprite(material);
  sprite.position.set(x, y + 1, z);
  sprite.scale.set(2, 2, 1);

  return sprite;
};

// 添加鼠标悬停交互
const addHoverInteraction = (mesh, element, x, y, z) => {
  // 存储原子信息用于悬停显示
  mesh.userData = { element, position: { x, y, z } };
  
  // 添加鼠标悬停事件
  mesh.addEventListener('mouseenter', (event) => {
    showAtomInfo(mesh.userData);
  });
  
  mesh.addEventListener('mouseleave', (event) => {
    hideAtomInfo();
  });
};

// 显示原子信息
const showAtomInfo = (atomData) => {
  // 移除现有的信息提示
  hideAtomInfo();
  
  // 创建信息提示元素
  const infoDiv = document.createElement('div');
  infoDiv.className = 'atom-info-tooltip';
  infoDiv.innerHTML = `
    <div class="atom-info-content">
      <strong>${atomData.element}</strong><br>
      Position: (${atomData.position.x.toFixed(2)},
                ${atomData.position.y.toFixed(2)},
                ${atomData.position.z.toFixed(2)})<br>
      Radius: ${(atomRadii[atomData.element] || atomRadii['default']).toFixed(2)} Å
    </div>
  `;
  
  infoDiv.style.position = 'absolute';
  infoDiv.style.top = '10px';
  infoDiv.style.left = '10px';
  infoDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
  infoDiv.style.color = 'white';
  infoDiv.style.padding = '10px';
  infoDiv.style.borderRadius = '5px';
  infoDiv.style.fontFamily = 'Arial, sans-serif';
  infoDiv.style.fontSize = '12px';
  infoDiv.style.zIndex = '2000';
  infoDiv.style.maxWidth = '200px';
  
  if (container.value) {
    container.value.appendChild(infoDiv);
  }
};

// 隐藏原子信息
const hideAtomInfo = () => {
  if (container.value) {
    const existingTooltip = container.value.querySelector('.atom-info-tooltip');
    if (existingTooltip) {
      container.value.removeChild(existingTooltip);
    }
  }
};

// 添加额外的灯光以提高场景亮度
const addAdditionalLighting = () => {
  if (!scene.value) return;
  
  // 添加更强的环境光
  const strongAmbientLight = markRaw(new THREE.AmbientLight(0xffffff, 0.8));
  scene.value.add(strongAmbientLight);
  
  // 添加额外的点光源
  const pointLight2 = markRaw(new THREE.PointLight(0xffffff, 0.7));
  pointLight2.position.set(-5, -5, 5);
  scene.value.add(pointLight2);
  
  const pointLight3 = markRaw(new THREE.PointLight(0xffffff, 0.6));
  pointLight3.position.set(0, 5, -5);
  scene.value.add(pointLight3);
  
  // 添加半球光
  const hemisphereLight = markRaw(new THREE.HemisphereLight(0xffffff, 0x444444, 0.6));
  scene.value.add(hemisphereLight);
  
};

// 创建原子图例
const createAtomLegend = () => {
  // 获取当前分子中实际存在的元素类型
  const elementsInMolecule = new Set();
  
  // 遍历场景中的所有网格对象来收集实际存在的元素
  if (scene.value) {
    scene.value.children.forEach(child => {
      if (child.isMesh && child.userData && child.userData.element) {
        elementsInMolecule.add(child.userData.element);
      }
    });
  }

  // 如果没有找到元素，使用默认的空集合
  if (elementsInMolecule.size === 0) {
    console.log('No elements found in current molecule for legend');
    return;
  }

  console.log('Elements in current molecule for legend:', Array.from(elementsInMolecule));

  // 创建图例容器
  const legendContainer = document.createElement('div');
  legendContainer.className = 'atom-legend';
  legendContainer.style.position = 'absolute';
  legendContainer.style.top = '60px'; // 降低位置以避免与标题重叠
  legendContainer.style.right = '10px';
  legendContainer.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
  legendContainer.style.padding = '10px';
  legendContainer.style.borderRadius = '5px';
  legendContainer.style.color = 'white';
  legendContainer.style.fontFamily = 'Arial, sans-serif';
  legendContainer.style.fontSize = '12px';
  legendContainer.style.zIndex = '1000';
  legendContainer.style.maxWidth = '200px';
  legendContainer.style.backdropFilter = 'blur(4px)';
  legendContainer.style.border = '1px solid rgba(255, 255, 255, 0.2)';

  // 添加标题
  const title = document.createElement('h3');
  title.textContent = '原子图例';
  title.style.margin = '0 0 10px 0';
  title.style.fontSize = '14px';
  title.style.borderBottom = '1px solid #555';
  title.style.paddingBottom = '5px';
  legendContainer.appendChild(title);

  // 为当前分子中存在的每个元素创建图例项
  Array.from(elementsInMolecule).sort().forEach(element => {
    const legendItem = document.createElement('div');
    legendItem.className = 'legend-item';
    legendItem.setAttribute('data-element', element);
    legendItem.style.display = 'flex';
    legendItem.style.alignItems = 'center';
    legendItem.style.marginBottom = '8px';
    legendItem.style.cursor = 'pointer';
    legendItem.style.transition = 'all 0.2s ease';
    
    // 添加点击事件来切换元素可见性
    legendItem.addEventListener('click', () => {
      toggleElementVisibility(element);
    });

    // 计算原子半径比例（相对于最大半径）
    const maxRadius = Math.max(...Object.values(atomRadii).filter(val => typeof val === 'number'));
    const elementRadius = atomRadii[element] || atomRadii['default'];
    const scaleFactor = 0.8; // 缩放因子，使图例大小更合适
    const circleSize = Math.max(8, Math.min(20, (elementRadius / maxRadius) * 20 * scaleFactor));

    // 创建圆形颜色标识
    const colorCircle = document.createElement('div');
    colorCircle.style.width = `${circleSize}px`;
    colorCircle.style.height = `${circleSize}px`;
    colorCircle.style.backgroundColor = `#${(atomColors[element] || atomColors['default']).toString(16).padStart(6, '0')}`;
    colorCircle.style.marginRight = '10px';
    colorCircle.style.borderRadius = '50%'; // 圆形
    colorCircle.style.border = '1px solid rgba(255, 255, 255, 0.3)';
    colorCircle.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.3)';
    colorCircle.style.transition = 'all 0.2s ease';

    // 元素名称和半径
    const label = document.createElement('span');
    const radius = atomRadii[element] || atomRadii['default'];
    label.textContent = `${element} (${radius.toFixed(2)} Å)`;
    label.style.flex = '1';
    label.style.fontSize = '11px';
    label.style.transition = 'all 0.2s ease';

    legendItem.appendChild(colorCircle);
    legendItem.appendChild(label);
    legendContainer.appendChild(legendItem);
  });

  // 初始更新图例样式
  updateLegendStyles();

  // 添加到容器
  if (container.value) {
    // 移除现有的图例
    const existingLegend = container.value.querySelector('.atom-legend');
    if (existingLegend) {
      container.value.removeChild(existingLegend);
    }
    container.value.appendChild(legendContainer);
  }
};

// 切换元素可见性
const toggleElementVisibility = (element) => {
  console.log('Toggling element visibility:', element);
  console.log('Crystal mode:', props.crystalMode);
  console.log('Unit cells:', props.unitCells);
  
  if (hiddenElements.value.has(element)) {
    // 显示该元素的所有原子
    hiddenElements.value.delete(element);
    console.log('Showing element:', element);
    
    // 在晶体模式下，需要重新添加该元素的所有原子到所有晶胞
    if (props.crystalMode) {
      console.log('Re-adding element in crystal mode:', element);
      reAddElementInCrystalMode(element);
    } else {
      // 重新创建并添加该元素的所有原子（单个晶胞模式）
      if (props.structureData && props.structureData.sites) {
        const lattice = props.structureData.lattice;
        let atomsAdded = 0;
        
        props.structureData.sites.forEach(atom => {
          let elementSymbol = '';
          
          if (atom.species && atom.species.length > 0) {
            elementSymbol = atom.species[0];
          } else if (atom.label) {
            elementSymbol = atom.label;
          }
          
          elementSymbol = elementSymbol.replace(/[0-9+-]/g, '');
          
          if (!elementSymbol) {
            elementSymbol = 'Si';
          }
          
          // 只处理当前要显示的元素
          if (elementSymbol === element) {
            // 检查是否已经存在相同位置的原子（防止重复添加）
            const x = (atom.xyz[0] - 0.5) * lattice.a;
            const y = (atom.xyz[1] - 0.5) * lattice.b;
            const z = (atom.xyz[2] - 0.5) * lattice.c;
            
            let atomExists = false;
            scene.value.children.forEach(child => {
              if (child.isMesh && child.userData && child.userData.element === element) {
                const childPos = child.position;
                const distance = Math.sqrt(
                  Math.pow(childPos.x - x, 2) +
                  Math.pow(childPos.y - y, 2) +
                  Math.pow(childPos.z - z, 2)
                );
                if (distance < 0.01) { // 使用更小的距离阈值来精确匹配
                  atomExists = true;
                }
              }
            });
            
            if (!atomExists) {
              const color = atomColors[elementSymbol] || atomColors['default'];
              // 根据当前显示模式设置原子半径
              let radius;
              if (props.displayMode === 'stick') {
                radius = (atomRadii[elementSymbol] || atomRadii['default']) * 0.5; // 棍球模式：50%
              } else {
                radius = (atomRadii[elementSymbol] || atomRadii['default']) * 1.2; // 球体模式：120%
              }
              
              const geometry = new THREE.SphereGeometry(radius, 32, 32);
              const material = new THREE.MeshPhongMaterial({ color });
              const sphere = markRaw(new THREE.Mesh(geometry, material));
              
              sphere.position.set(x, y, z);
              
              // 存储原子信息
              sphere.userData = {
                element: elementSymbol,
                position: { x, y, z },
                visible: true
              };
              
              // 添加鼠标悬停交互
              addHoverInteraction(sphere, elementSymbol, x, y, z);
              
              // 添加到场景
              scene.value.add(sphere);
              atomsAdded++;
              
              // 如果是棍球模式，还需要重新创建化学键
              if (props.displayMode === 'stick') {
                recreateBondsForAtom(elementSymbol, x, y, z, lattice);
              }
            } else {
              console.log('Atom already exists at position:', {x, y, z});
            }
          }
        });
        
        console.log(`Added ${atomsAdded} atoms of element ${element} to scene`);
      }
    }
  } else {
    // 隐藏该元素的所有原子
    hiddenElements.value.add(element);
    console.log('Hiding element:', element);
    
    // 从场景中移除该元素的所有原子
    const atomsToRemove = [];
    scene.value.children.forEach(child => {
      if (child.isMesh && child.userData && child.userData.element === element) {
        atomsToRemove.push(child);
      }
    });
    
    console.log(`Removing ${atomsToRemove.length} atoms of element ${element}`);
    atomsToRemove.forEach(atom => {
      scene.value.remove(atom);
    });
  }
  
  // 更新图例样式
  updateLegendStyles();
  console.log('Hidden elements updated:', Array.from(hiddenElements.value));
};

// 更新图例样式
const updateLegendStyles = () => {
  if (!container.value) return;
  
  const legendItems = container.value.querySelectorAll('.atom-legend .legend-item');
  legendItems.forEach(item => {
    const element = item.getAttribute('data-element');
    if (hiddenElements.value.has(element)) {
      item.style.opacity = '0.4';
      item.style.textDecoration = 'line-through';
    } else {
      item.style.opacity = '1';
      item.style.textDecoration = 'none';
    }
  });
};

// 创建分子标题
const createMoleculeTitle = () => {
  if (!container.value) return;
  
  // 移除现有的标题
  const existingTitle = container.value.querySelector('.molecule-title');
  if (existingTitle) {
    container.value.removeChild(existingTitle);
  }
  
  // 获取分子名称和化学式
  let formula = 'Unknown';
  let materialId = 'Unknown';
  
  if (props.materialData && props.materialData.formula_pretty) {
    formula = props.materialData.formula_pretty;
  }
  
  if (props.materialId) {
    materialId = props.materialId;
  } else if (props.structureData && props.structureData.material_id) {
    materialId = props.structureData.material_id;
  }
  
  // 创建标题容器
  const titleContainer = document.createElement('div');
  titleContainer.className = 'molecule-title';
  titleContainer.style.position = 'absolute';
  titleContainer.style.top = '10px';
  titleContainer.style.left = '10px';
  titleContainer.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
  titleContainer.style.padding = '10px 15px';
  titleContainer.style.borderRadius = '5px';
  titleContainer.style.color = 'white';
  titleContainer.style.fontFamily = 'Arial, sans-serif';
  titleContainer.style.fontSize = '14px';
  titleContainer.style.zIndex = '1000';
  titleContainer.style.maxWidth = '300px';
  titleContainer.style.backdropFilter = 'blur(4px)';
  titleContainer.style.border = '1px solid rgba(255, 255, 255, 0.2)';
  
  // 添加标题内容
  titleContainer.innerHTML = `
    <div style="font-weight: bold; margin-bottom: 5px; color: #4facfe;">${formula}</div>
    <div style="font-size: 12px; opacity: 0.8;">Material ID: ${materialId}</div>
  `;
  
  container.value.appendChild(titleContainer);
};

const handleResize = () => {
  if (container.value && camera.value && renderer.value) {
    camera.value.aspect = container.value.clientWidth / container.value.clientHeight;
    camera.value.updateProjectionMatrix();
    renderer.value.setSize(container.value.clientWidth, container.value.clientHeight);
  }
};

watch(() => props.structureData, (newData, oldData) => {
  console.log('Structure data changed - old:', oldData, 'new:', newData);
  console.log('New data type:', typeof newData);
  console.log('New data is null:', newData === null);
  console.log('New data is undefined:', newData === undefined);
  console.log('Current hidden elements:', Array.from(hiddenElements.value));
  
  if (newData) {
    console.log('New data properties:', Object.keys(newData));
    console.log('Scene available:', !!scene.value);
    console.log('Structure data has sites:', newData.sites?.length, 'atoms');
    console.log('Structure data has lattice:', !!newData.lattice);
    console.log('Structure data material_id:', newData.material_id);
    loading.value = false;
    
    // Check if we need to wait for scene initialization
    if (scene.value) {
      console.log('Scene is ready, calling renderMolecule');
      renderMolecule(newData);
    } else {
      console.log('Scene not ready yet, will render when scene is initialized');
      // Scene will be initialized in onMounted, which will call renderMolecule if data is available
    }
  } else {
    console.log('No structure data received - value:', newData);
  }
}, { immediate: true, deep: true });

watch(() => props.materialId, (newId) => {
  console.log('Material ID prop changed:', newId);
  if (newId) {
    loading.value = true;
    error.value = '';
  }
});

onMounted(() => {
  console.log('MoleculeViewer component mounted with key:', props.materialId);
  console.log('Component mounted, container:', container.value);
  console.log('Initial hidden elements state:', Array.from(hiddenElements.value));
  
  if (!container.value) {
    error.value = 'Container element is null!';
    console.error('Container element is null!');
    return;
  }
  
  // Check WebGL support
  if (!isWebGLAvailable()) {
    error.value = 'WebGL is not supported in your browser. Please use a modern browser that supports WebGL.';
    console.error('WebGL not available');
    return;
  }
  
  console.log('WebGL is available, initializing Three.js...');
  
  // Wait for next tick to ensure DOM is fully rendered
  setTimeout(() => {
    console.log('Initializing Three.js...');
    initThreeJS();
    console.log('Three.js initialized, scene:', scene.value);
    
    // Check if structureData is already available and scene is ready
    console.log('Current structureData prop:', props.structureData);
    console.log('StructureData prop type:', typeof props.structureData);
    console.log('StructureData is null:', props.structureData === null);
    console.log('StructureData is undefined:', props.structureData === undefined);
    
    // Small delay to ensure component is fully mounted
    setTimeout(() => {
      console.log('Checking structure data after mount delay...');
      console.log('props.structureData:', props.structureData);
      console.log('scene.value:', !!scene.value);
      console.log('Current hidden elements:', Array.from(hiddenElements.value));
      
      if (props.structureData && scene.value) {
        console.log('Structure data available and scene ready, rendering molecule...');
        console.log('Structure data type:', typeof props.structureData);
        console.log('Structure data keys:', Object.keys(props.structureData));
        renderMolecule(props.structureData);
      } else if (props.structureData && !scene.value) {
        console.log('Structure data available but scene not ready yet');
      } else {
        console.log('No structure data available yet - value:', props.structureData);
      }
    }, 100);
    
    window.addEventListener('resize', handleResize);
  }, 100);
});

const isWebGLAvailable = () => {
  try {
    const canvas = document.createElement('canvas');
    return !!(window.WebGLRenderingContext &&
      (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')));
  } catch (e) {
    return false;
  }
};


// Watch for material ID changes to force re-render
watch(() => props.materialId, (newId, oldId) => {
  console.log('Material ID changed - old:', oldId, 'new:', newId);
  if (newId && props.structureData && scene.value) {
    console.log('Re-rendering molecule due to material ID change');
    renderMolecule(props.structureData);
  }
});

// Watch for display mode changes to force re-render
watch(() => props.displayMode, (newMode, oldMode) => {
  console.log('Display mode changed - old:', oldMode, 'new:', newMode);
  if (props.structureData && scene.value) {
    console.log('Re-rendering molecule due to display mode change');
    renderMolecule(props.structureData);
  }
});

// Watch for crystal mode changes to force re-render
watch(() => props.crystalMode, (newMode, oldMode) => {
  console.log('Crystal mode changed - old:', oldMode, 'new:', newMode);
  if (props.structureData && scene.value) {
    console.log('Re-rendering molecule due to crystal mode change');
    renderMolecule(props.structureData);
  }
});

// Watch for unit cells changes to force re-render
watch(() => props.unitCells, (newCells, oldCells) => {
  console.log('Unit cells changed - old:', oldCells, 'new:', newCells);
  if (props.structureData && scene.value) {
    console.log('Re-rendering molecule due to unit cells change');
    renderMolecule(props.structureData);
  }
});

onUnmounted(() => {
  console.log('MoleculeViewer component unmounted');
  if (animationId) {
    cancelAnimationFrame(animationId);
    animationId = null;
  }
  window.removeEventListener('resize', handleResize);
  
  if (renderer.value) {
    renderer.value.dispose();
    renderer.value = null;
  }
  
  if (scene.value) {
    // Clear all objects from scene
    while(scene.value.children.length > 0) {
      scene.value.remove(scene.value.children[0]);
    }
    scene.value = null;
  }
  
  if (camera.value) {
    camera.value = null;
  }
  
  if (controls.value) {
    controls.value = null;
  }
});
// 球体模式渲染
const renderBallMode = (atoms, lattice) => {
  console.log('Rendering in ball mode');
  
  atoms.forEach((atom) => {
    // 提取元素符号 - 优先使用species数组，然后使用label
    let elementSymbol = '';
    
    if (atom.species && atom.species.length > 0) {
      elementSymbol = atom.species[0];
    } else if (atom.label) {
      elementSymbol = atom.label;
    }
    
    // 清理元素符号（移除数字和特殊字符）
    elementSymbol = elementSymbol.replace(/[0-9+-]/g, '');
    
    // 如果无法提取元素符号，使用默认值
    if (!elementSymbol) {
      elementSymbol = 'Si'; // 默认为硅
    }

    const color = atomColors[elementSymbol] || atomColors['default'];
    const radius = (atomRadii[elementSymbol] || atomRadii['default']) * 1.2;

    const geometry = new THREE.SphereGeometry(radius, 32, 32);
    const material = new THREE.MeshPhongMaterial({ color });
    const sphere = markRaw(new THREE.Mesh(geometry, material));

    // 将分数坐标转换为笛卡尔坐标
    const x = (atom.xyz[0] - 0.5) * lattice.a;
    const y = (atom.xyz[1] - 0.5) * lattice.b;
    const z = (atom.xyz[2] - 0.5) * lattice.c;

    sphere.position.set(x, y, z);
    
    // 存储原子信息用于悬停显示和可见性控制
    sphere.userData = {
      element: elementSymbol,
      position: { x, y, z },
      visible: !hiddenElements.value.has(elementSymbol)
    };
    
    // 添加鼠标悬停交互
    addHoverInteraction(sphere, elementSymbol, x, y, z);
    
    // 如果该元素类型被隐藏，则不添加到场景中
    if (!hiddenElements.value.has(elementSymbol)) {
      scene.value.add(sphere);
    } else {
      console.log('Skipping atom of hidden element:', elementSymbol);
    }
  });
};

// 棍球模式渲染
const renderStickMode = (atoms, lattice) => {
  console.log('Rendering in stick mode');
  
  const bondDistanceThreshold = 2.0; // 键长阈值（Å）
  const bondRadius = 0.1; // 键的半径
  
  // 创建原子（小球体）
  atoms.forEach((atom) => {
    let elementSymbol = '';
    
    if (atom.species && atom.species.length > 0) {
      elementSymbol = atom.species[0];
    } else if (atom.label) {
      elementSymbol = atom.label;
    }
    
    elementSymbol = elementSymbol.replace(/[0-9+-]/g, '');
    
    if (!elementSymbol) {
      elementSymbol = 'Si';
    }

    const color = atomColors[elementSymbol] || atomColors['default'];
    const radius = (atomRadii[elementSymbol] || atomRadii['default']) * 0.5; // 棍球模式下原子半径减小

    const geometry = new THREE.SphereGeometry(radius, 16, 16);
    const material = new THREE.MeshPhongMaterial({ color });
    const sphere = markRaw(new THREE.Mesh(geometry, material));

    const x = (atom.xyz[0] - 0.5) * lattice.a;
    const y = (atom.xyz[1] - 0.5) * lattice.b;
    const z = (atom.xyz[2] - 0.5) * lattice.c;

    sphere.position.set(x, y, z);
    
    sphere.userData = {
      element: elementSymbol,
      position: { x, y, z },
      visible: !hiddenElements.value.has(elementSymbol)
    };
    
    addHoverInteraction(sphere, elementSymbol, x, y, z);
    
    if (!hiddenElements.value.has(elementSymbol)) {
      scene.value.add(sphere);
    } else {
      console.log('Skipping atom of hidden element in stick mode:', elementSymbol);
    }
  });

  // 创建化学键（圆柱体）
  for (let i = 0; i < atoms.length; i++) {
    for (let j = i + 1; j < atoms.length; j++) {
      const atom1 = atoms[i];
      const atom2 = atoms[j];
      
      let elementSymbol1 = '';
      if (atom1.species && atom1.species.length > 0) {
        elementSymbol1 = atom1.species[0];
      } else if (atom1.label) {
        elementSymbol1 = atom1.label;
      }
      elementSymbol1 = elementSymbol1.replace(/[0-9+-]/g, '');
      
      let elementSymbol2 = '';
      if (atom2.species && atom2.species.length > 0) {
        elementSymbol2 = atom2.species[0];
      } else if (atom2.label) {
        elementSymbol2 = atom2.label;
      }
      elementSymbol2 = elementSymbol2.replace(/[0-9+-]/g, '');
      
      // 如果任一元素被隐藏，跳过创建键
      if (hiddenElements.value.has(elementSymbol1) || hiddenElements.value.has(elementSymbol2)) {
        continue;
      }

      const x1 = (atom1.xyz[0] - 0.5) * lattice.a;
      const y1 = (atom1.xyz[1] - 0.5) * lattice.b;
      const z1 = (atom1.xyz[2] - 0.5) * lattice.c;

      const x2 = (atom2.xyz[0] - 0.5) * lattice.a;
      const y2 = (atom2.xyz[1] - 0.5) * lattice.b;
      const z2 = (atom2.xyz[2] - 0.5) * lattice.c;

      const distance = Math.sqrt(
        Math.pow(x2 - x1, 2) +
        Math.pow(y2 - y1, 2) +
        Math.pow(z2 - z1, 2)
      );

      // 如果距离小于阈值，创建化学键
      if (distance < bondDistanceThreshold) {
        // 更简单的方法：使用 Three.js 的 Object3D.lookAt() 方法
        const cylinderGeometry = new THREE.CylinderGeometry(
          bondRadius,
          bondRadius,
          distance,
          8
        );
        
        const cylinderMaterial = new THREE.MeshPhongMaterial({
          color: 0xCCCCCC // 键的颜色为灰色
        });
        const cylinder = markRaw(new THREE.Mesh(cylinderGeometry, cylinderMaterial));
        
        // 将圆柱体放置在第一个原子的位置
        cylinder.position.set(x1, y1, z1);
        
        // 使用 lookAt 方法使圆柱体指向第二个原子
        cylinder.lookAt(new THREE.Vector3(x2, y2, z2));
        
        // 由于圆柱体默认沿Y轴，需要旋转90度使其沿Z轴
        cylinder.rotateX(Math.PI / 2);
        
        // 将圆柱体移动到两个原子的中间位置
        cylinder.position.set(
          (x1 + x2) / 2,
          (y1 + y2) / 2,
          (z1 + z2) / 2
        );
        
        scene.value.add(cylinder);
      }
    }
  }
};

// 为特定原子重新创建化学键（棍球模式下使用）
const recreateBondsForAtom = (elementSymbol, x, y, z, lattice) => {
  if (props.displayMode !== 'stick') return;
  
  const bondDistanceThreshold = 2.0;
  const bondRadius = 0.1;
  
  // 遍历场景中的所有原子，检查是否需要创建化学键
  scene.value.children.forEach(child => {
    if (child.isMesh && child.userData && child.userData.element && child.userData.visible) {
      const otherElement = child.userData.element;
      const otherX = child.userData.position.x;
      const otherY = child.userData.position.y;
      const otherZ = child.userData.position.z;
      
      // 跳过自身和隐藏的元素
      if (otherElement === elementSymbol &&
          Math.abs(otherX - x) < 0.001 &&
          Math.abs(otherY - y) < 0.001 &&
          Math.abs(otherZ - z) < 0.001) {
        return;
      }
      
      const distance = Math.sqrt(
        Math.pow(otherX - x, 2) +
        Math.pow(otherY - y, 2) +
        Math.pow(otherZ - z, 2)
      );
      
      // 如果距离小于阈值，创建化学键
      if (distance < bondDistanceThreshold) {
        // 更简单的方法：使用 Three.js 的 Object3D.lookAt() 方法
        const cylinderGeometry = new THREE.CylinderGeometry(
          bondRadius,
          bondRadius,
          distance,
          8
        );
        
        const cylinderMaterial = new THREE.MeshPhongMaterial({
          color: 0xCCCCCC // 键的颜色为灰色
        });
        const cylinder = markRaw(new THREE.Mesh(cylinderGeometry, cylinderMaterial));
        
        // 将圆柱体放置在第一个原子的位置
        cylinder.position.set(x, y, z);
        
        // 使用 lookAt 方法使圆柱体指向第二个原子
        cylinder.lookAt(new THREE.Vector3(otherX, otherY, otherZ));
        
        // 由于圆柱体默认沿Y轴，需要旋转90度使其沿Z轴
        cylinder.rotateX(Math.PI / 2);
        
        // 将圆柱体移动到两个原子的中间位置
        cylinder.position.set(
          (x + otherX) / 2,
          (y + otherY) / 2,
          (z + otherZ) / 2
        );
        
        scene.value.add(cylinder);
      }
    }
  });
};

// 晶体结构渲染
const renderCrystalStructure = (atoms, lattice) => {
  console.log('Rendering crystal structure with', props.unitCells, 'unit cells');
  
  // 首先渲染晶胞边界框
  renderUnitCellBoundary(lattice);
  
  // 然后渲染原子（扩展到多个晶胞）
  renderExtendedAtoms(atoms, lattice);
  
  // 如果是棍球模式，还需要渲染化学键
  if (props.displayMode === 'stick') {
    renderExtendedBonds(atoms, lattice);
  }
};

// 渲染晶胞边界框
const renderUnitCellBoundary = (lattice) => {
  console.log('Rendering unit cell boundary with', props.unitCells, 'unit cells');
  
  const a = lattice.a;
  const b = lattice.b;
  const c = lattice.c;
  const unitCells = props.unitCells;
  
  // 计算扩展范围
  const range = Math.floor(unitCells / 2);
  
  for (let i = -range; i <= range; i++) {
    for (let j = -range; j <= range; j++) {
      for (let k = -range; k <= range; k++) {
        // 创建晶胞边界框的几何体
        const edges = [
          // 底面
          [0, 0, 0], [a, 0, 0],
          [0, 0, 0], [0, b, 0],
          [a, 0, 0], [a, b, 0],
          [0, b, 0], [a, b, 0],
          
          // 顶面
          [0, 0, c], [a, 0, c],
          [0, 0, c], [0, b, c],
          [a, 0, c], [a, b, c],
          [0, b, c], [a, b, c],
          
          // 侧面
          [0, 0, 0], [0, 0, c],
          [a, 0, 0], [a, 0, c],
          [0, b, 0], [0, b, c],
          [a, b, 0], [a, b, c]
        ];
        
        const points = [];
        edges.forEach(edge => {
          points.push(new THREE.Vector3(
            edge[0] - a/2 + i * a,
            edge[1] - b/2 + j * b,
            edge[2] - c/2 + k * c
          ));
        });
        
        const geometry = new THREE.BufferGeometry().setFromPoints(points);
        const material = new THREE.LineBasicMaterial({
          color: 0x00ffff,
          transparent: true,
          opacity: 0.6,
          linewidth: 2
        });
        
        const line = markRaw(new THREE.LineSegments(geometry, material));
        scene.value.add(line);
        
        // 添加半透明面渲染（30%透明度）
        const faces = [
          // 底面
          [0, 0, 0], [a, 0, 0], [a, b, 0], [0, b, 0],
          // 顶面
          [0, 0, c], [a, 0, c], [a, b, c], [0, b, c],
          // 前面
          [0, 0, 0], [a, 0, 0], [a, 0, c], [0, 0, c],
          // 后面
          [0, b, 0], [a, b, 0], [a, b, c], [0, b, c],
          // 左面
          [0, 0, 0], [0, b, 0], [0, b, c], [0, 0, c],
          // 右面
          [a, 0, 0], [a, b, 0], [a, b, c], [a, 0, c]
        ];
        
        // 为每个面创建几何体
        for (let faceIndex = 0; faceIndex < 6; faceIndex++) {
          const faceVertices = [];
          for (let vertexIndex = 0; vertexIndex < 4; vertexIndex++) {
            const vertex = faces[faceIndex * 4 + vertexIndex];
            faceVertices.push(new THREE.Vector3(
              vertex[0] - a/2 + i * a,
              vertex[1] - b/2 + j * b,
              vertex[2] - c/2 + k * c
            ));
          }
          
          const faceGeometry = new THREE.BufferGeometry().setFromPoints(faceVertices);
          const faceMaterial = new THREE.MeshBasicMaterial({
            color: 0x00ffff,
            transparent: true,
            opacity: 0.3, // 30%透明度
            side: THREE.DoubleSide
          });
          
          const faceMesh = markRaw(new THREE.Mesh(faceGeometry, faceMaterial));
          scene.value.add(faceMesh);
        }
      }
    }
  }
};

// 渲染扩展到多个晶胞的原子
const renderExtendedAtoms = (atoms, lattice) => {
  console.log('Rendering extended atoms');
  
  const a = lattice.a;
  const b = lattice.b;
  const c = lattice.c;
  const unitCells = props.unitCells;
  
  // 计算扩展范围
  const range = Math.floor(unitCells / 2);
  
  for (let i = -range; i <= range; i++) {
    for (let j = -range; j <= range; j++) {
      for (let k = -range; k <= range; k++) {
        atoms.forEach((atom) => {
          let elementSymbol = '';
          
          if (atom.species && atom.species.length > 0) {
            elementSymbol = atom.species[0];
          } else if (atom.label) {
            elementSymbol = atom.label;
          }
          
          elementSymbol = elementSymbol.replace(/[0-9+-]/g, '');
          
          if (!elementSymbol) {
            elementSymbol = 'Si';
          }

          const color = atomColors[elementSymbol] || atomColors['default'];
          const radius = (atomRadii[elementSymbol] || atomRadii['default']) * 0.8; // 晶体模式下原子稍小

          const geometry = new THREE.SphereGeometry(radius, 16, 16);
          const material = new THREE.MeshPhongMaterial({ color });
          const sphere = markRaw(new THREE.Mesh(geometry, material));

          // 将分数坐标转换为笛卡尔坐标，并扩展到多个晶胞
          const x = (atom.xyz[0] + i - 0.5) * a;
          const y = (atom.xyz[1] + j - 0.5) * b;
          const z = (atom.xyz[2] + k - 0.5) * c;

          sphere.position.set(x, y, z);
          
          sphere.userData = {
            element: elementSymbol,
            position: { x, y, z },
            visible: !hiddenElements.value.has(elementSymbol)
          };
          
          addHoverInteraction(sphere, elementSymbol, x, y, z);
          
          // 只在元素未被隐藏时添加到场景中
          if (!hiddenElements.value.has(elementSymbol)) {
            scene.value.add(sphere);
          }
        });
      }
    }
  }
};

// 渲染扩展到多个晶胞的化学键（棍球模式）
const renderExtendedBonds = (atoms, lattice) => {
  console.log('Rendering extended bonds');
  
  const a = lattice.a;
  const b = lattice.b;
  const c = lattice.c;
  const unitCells = props.unitCells;
  const bondDistanceThreshold = 2.5; // 晶体模式下键长阈值稍大
  const bondRadius = 0.08; // 晶体模式下键更细
  
  const range = Math.floor(unitCells / 2);
  
  for (let i = -range; i <= range; i++) {
    for (let j = -range; j <= range; j++) {
      for (let k = -range; k <= range; k++) {
        // 在当前晶胞内创建化学键
        for (let idx1 = 0; idx1 < atoms.length; idx1++) {
          for (let idx2 = idx1 + 1; idx2 < atoms.length; idx2++) {
            const atom1 = atoms[idx1];
            const atom2 = atoms[idx2];
            
            let elementSymbol1 = '';
            if (atom1.species && atom1.species.length > 0) {
              elementSymbol1 = atom1.species[0];
            } else if (atom1.label) {
              elementSymbol1 = atom1.label;
            }
            elementSymbol1 = elementSymbol1.replace(/[0-9+-]/g, '');
            
            let elementSymbol2 = '';
            if (atom2.species && atom2.species.length > 0) {
              elementSymbol2 = atom2.species[0];
            } else if (atom2.label) {
              elementSymbol2 = atom2.label;
            }
            elementSymbol2 = elementSymbol2.replace(/[0-9+-]/g, '');
            
            // 如果任一元素被隐藏，跳过创建键
            if (hiddenElements.value.has(elementSymbol1) || hiddenElements.value.has(elementSymbol2)) {
              continue;
            }

            const x1 = (atom1.xyz[0] + i - 0.5) * a;
            const y1 = (atom1.xyz[1] + j - 0.5) * b;
            const z1 = (atom1.xyz[2] + k - 0.5) * c;

            const x2 = (atom2.xyz[0] + i - 0.5) * a;
            const y2 = (atom2.xyz[1] + j - 0.5) * b;
            const z2 = (atom2.xyz[2] + k - 0.5) * c;

            const distance = Math.sqrt(
              Math.pow(x2 - x1, 2) +
              Math.pow(y2 - y1, 2) +
              Math.pow(z2 - z1, 2)
            );

            // 如果距离小于阈值，创建化学键
            if (distance < bondDistanceThreshold) {
              const cylinderGeometry = new THREE.CylinderGeometry(
                bondRadius,
                bondRadius,
                distance,
                6
              );
              
              const cylinderMaterial = new THREE.MeshPhongMaterial({
                color: 0xCCCCCC
              });
              const cylinder = markRaw(new THREE.Mesh(cylinderGeometry, cylinderMaterial));
              
              cylinder.position.set(x1, y1, z1);
              cylinder.lookAt(new THREE.Vector3(x2, y2, z2));
              cylinder.rotateX(Math.PI / 2);
              cylinder.position.set(
                (x1 + x2) / 2,
                (y1 + y2) / 2,
                (z1 + z2) / 2
              );
              
              scene.value.add(cylinder);
            }
          }
        }
      }
    }
  }
};

// 在晶体模式下重新添加特定元素的所有原子
const reAddElementInCrystalMode = (element) => {
  console.log('Re-adding element in crystal mode:', element);
  
  if (!props.structureData || !props.structureData.sites || !props.structureData.lattice) {
    console.error('Cannot re-add element: structure data missing');
    return;
  }
  
  const atoms = props.structureData.sites;
  const lattice = props.structureData.lattice;
  const a = lattice.a;
  const b = lattice.b;
  const c = lattice.c;
  const unitCells = props.unitCells;
  
  // 计算扩展范围
  const range = Math.floor(unitCells / 2);
  let atomsAdded = 0;
  
  for (let i = -range; i <= range; i++) {
    for (let j = -range; j <= range; j++) {
      for (let k = -range; k <= range; k++) {
        atoms.forEach((atom) => {
          let elementSymbol = '';
          
          if (atom.species && atom.species.length > 0) {
            elementSymbol = atom.species[0];
          } else if (atom.label) {
            elementSymbol = atom.label;
          }
          
          elementSymbol = elementSymbol.replace(/[0-9+-]/g, '');
          
          if (!elementSymbol) {
            elementSymbol = 'Si';
          }
          
          // 只处理当前要显示的元素
          if (elementSymbol === element) {
            const x = (atom.xyz[0] + i - 0.5) * a;
            const y = (atom.xyz[1] + j - 0.5) * b;
            const z = (atom.xyz[2] + k - 0.5) * c;
            
            // 检查是否已经存在相同位置的原子（防止重复添加）
            let atomExists = false;
            scene.value.children.forEach(child => {
              if (child.isMesh && child.userData && child.userData.element === element) {
                const childPos = child.position;
                const distance = Math.sqrt(
                  Math.pow(childPos.x - x, 2) +
                  Math.pow(childPos.y - y, 2) +
                  Math.pow(childPos.z - z, 2)
                );
                if (distance < 0.01) { // 使用更小的距离阈值来精确匹配
                  atomExists = true;
                }
              }
            });
            
            if (!atomExists) {
              const color = atomColors[elementSymbol] || atomColors['default'];
              const radius = (atomRadii[elementSymbol] || atomRadii['default']) * 0.8;
              
              const geometry = new THREE.SphereGeometry(radius, 16, 16);
              const material = new THREE.MeshPhongMaterial({ color });
              const sphere = markRaw(new THREE.Mesh(geometry, material));
              
              sphere.position.set(x, y, z);
              
              // 存储原子信息
              sphere.userData = {
                element: elementSymbol,
                position: { x, y, z },
                visible: true
              };
              
              // 添加鼠标悬停交互
              addHoverInteraction(sphere, elementSymbol, x, y, z);
              
              // 添加到场景
              scene.value.add(sphere);
              atomsAdded++;
            }
          }
        });
      }
    }
  }
  
  console.log(`Added ${atomsAdded} atoms of element ${element} in crystal mode`);
};

</script>

<style scoped>
.molecule-viewer {
  position: relative;
  width: 100%;
  height: 500px;
  border: 2px solid #007bff;
  border-radius: 8px;
  overflow: hidden;
  background-color: #1a1a1a;
}

.viewer-container {
  width: 100%;
  height: 100%;
  display: block;
  position: relative;
}

.viewer-container canvas {
  display: block;
  width: 100%;
  height: 100%;
  outline: none;
}

.loading-overlay,
.error-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: rgba(0, 0, 0, 0.8);
  color: white;
  z-index: 1000;
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #333;
  border-top: 4px solid #007bff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 16px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.error-overlay p {
  color: #ff6b6b;
  font-weight: bold;
}
</style>

<style scoped>
/* 原子图例样式 */
.atom-legend {
  position: absolute;
  top: 60px;
  right: 10px;
  background-color: rgba(0, 0, 0, 0.8);
  padding: 10px;
  border-radius: 5px;
  color: white;
  font-family: Arial, sans-serif;
  font-size: 12px;
  z-index: 1000;
  max-width: 200px;
  backdrop-filter: blur(4px);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.atom-legend h3 {
  margin: 0 0 10px 0;
  font-size: 14px;
  border-bottom: 1px solid #555;
  padding-bottom: 5px;
}

.atom-legend div {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.atom-legend div div {
  border-radius: 50%;
  margin-right: 10px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

.atom-legend span {
  flex: 1;
  font-size: 11px;
}

/* 图例项悬停效果 */
.atom-legend .legend-item:hover {
  transform: translateX(2px);
}

.atom-legend .legend-item:hover div {
  transform: scale(1.1);
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.4);
}

/* 分子标题样式 */
.molecule-title {
  position: absolute;
  top: 10px;
  left: 10px;
  background-color: rgba(0, 0, 0, 0.8);
  padding: 10px 15px;
  border-radius: 5px;
  color: white;
  font-family: Arial, sans-serif;
  font-size: 14px;
  z-index: 1000;
  max-width: 300px;
  backdrop-filter: blur(4px);
  border: 1px solid rgba(255, 255, 255, 0.2);
}
</style>

<style>
/* 原子信息提示样式 */
.atom-info-tooltip {
  position: absolute;
  top: 10px;
  left: 10px;
  background-color: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 12px;
  border-radius: 6px;
  font-family: 'Arial', sans-serif;
  font-size: 12px;
  z-index: 2000;
  max-width: 250px;
  backdrop-filter: blur(4px);
  border: 1px solid rgba(255, 255, 255, 0.2);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

.atom-info-content {
  line-height: 1.5;
}

.atom-info-content strong {
  color: #4facfe;
  font-size: 14px;
}
</style>
